package com.solidtrust.admin.controller;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.solidtrust.entity.Brand;
import com.solidtrust.entity.CarImage;
import com.solidtrust.entity.Model;
import com.solidtrust.repository.BrandRepository;
import com.solidtrust.repository.CarImageRepository;
import com.solidtrust.repository.ModelRepository;

@Controller
@RequestMapping("map")
public class BrandModelMappingController {

	@PersistenceContext
	private EntityManager em;
	
	@Autowired BrandRepository brandRep;
	@Autowired ModelRepository modelRep;
	@Autowired CarImageRepository carImageRep;
	
	@RequestMapping("img")
	public String img(){
		return "admin/map/img.jsp";
	}
	
	@Transactional(readOnly = true)
	@ResponseBody
	@RequestMapping("brands")
	public Object getBrands(){
		
		// all standard brands
		List<Brand> standard = brandRep.findByStatus((short)1);
		
		// all car image brands
		String ql = "select distinct brand from CarImage";
		List<String> carImage = em.createQuery(ql, String.class).getResultList();
		ArrayNode array1 = new ArrayNode(JsonNodeFactory.instance);
		for (String s : carImage) {
			ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
			node.set("text", new TextNode(s));
			array1.add(node);
		}
		
		// merged brands
//		ql = "select distinct standardBrandId from CarImage where standardBrandId is not null";
		ql = "select distinct b.id from CarImage c join c.stardardBrands b";
		List<Integer> merged1 = em.createQuery(ql, Integer.class).getResultList();
		List<Brand> unmerged = new ArrayList<Brand>();
		List<Brand> merged = new ArrayList<Brand>();
		for (Brand b : standard) {
			if(!merged1.contains(b.getId())){
				unmerged.add(b);
			}else{
				merged.add(b);
			}
		}
		
		
		
		ArrayNode array2 = new ArrayNode(JsonNodeFactory.instance);
		for (Brand b : unmerged) {
			ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
			node.set("text", new TextNode(b.getBrand()));
			node.set("id", new TextNode(b.getId() + ""));
			array2.add(node);
		}
		
		ArrayNode array3 = new ArrayNode(JsonNodeFactory.instance);
		for (Brand b : merged) {
			ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
			node.set("text", new TextNode(b.getBrand()));
			node.set("id", new TextNode(b.getId() + ""));
			array3.add(node);
		}
		
		return new Object[]{array1, array2, array3};
	}
	
	@Transactional(readOnly = true)
	@ResponseBody
	@RequestMapping("models")
	public Object getModels(Integer brandId){
		// all standard models
		List<Model> standard = brandRep.findOne(brandId).getModels();
		
		// all car image models
		String ql = "select c.subBrand from CarImage c join c.stardardBrands b where b.id=" + brandId;
		List<String> carImage = em.createQuery(ql, String.class).getResultList();
		ArrayNode array1 = new ArrayNode(JsonNodeFactory.instance);
		for (String s : carImage) {
			ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
			node.set("text", new TextNode(s));
			array1.add(node);
		}
		
		// merged brands
		ql = "select m.id from CarImage c join c.stardardBrands b join c.standardModels m where b.id=" + brandId;
		List<Integer> merged1 = em.createQuery(ql, Integer.class).getResultList();
		List<Model> unmerged = new ArrayList<Model>();
		List<Model> merged = new ArrayList<Model>();
		for (Model b : standard) {
			if(!merged1.contains(b.getId())){
				unmerged.add(b);
			}else{
				merged.add(b);
			}
		}
		
		ArrayNode array2 = new ArrayNode(JsonNodeFactory.instance);
		for (Model b : unmerged) {
			ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
			node.set("text", new TextNode(b.getModel()));
			node.set("id", new TextNode(b.getId() + ""));
			array2.add(node);
		}
		
		ArrayNode array3 = new ArrayNode(JsonNodeFactory.instance);
		for (Model b : merged) {
			ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
			node.set("text", new TextNode(b.getModel()));
			node.set("id", new TextNode(b.getId() + ""));
			array3.add(node);
		}
		
		return new Object[]{array1, array2, array3};
	}
	
	@Transactional(readOnly = false)
	@ResponseBody
	@RequestMapping("mapImageBrand")
	public int mapImageBrand(Integer standardBrandId, String imageBrand){
		List<CarImage> list = carImageRep.findByBrand(imageBrand);
		Brand brand = brandRep.findOne(standardBrandId);
		brand.getImages().addAll(list);
		brandRep.save(brand);
		return list.size();
	}
	
	@Transactional(readOnly = false)
	@ResponseBody
	@RequestMapping("mapImageModel")
	public int mapImageModel(Integer standardBrandId, Integer standardModelId, String imageModel){
		List<CarImage> list = carImageRep.findBySubBrandAndBrandId(standardBrandId, imageModel);
		Model model = modelRep.findOne(standardModelId);
		model.setImage(list.get(0));
		return list.size();
	}
	
}
